package com.shanghaionstar.nav.presenter;

import android.content.res.Resources;
import android.location.Location;
import android.support.v4.app.FragmentManager;

import com.onstar.cn.auth.userProfile.FeatureEnum;
import com.onstar.cn.common.exception.HttpException;
import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.common.log.LogManager;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.framework.mvp.base.IMVPScheduler;
import com.onstar.cn.framework.mvp.base.IMVPView;
import com.onstar.cn.framework.mvp.base.core.BasePresenter;
import com.onstar.cn.framework.utils.RxBus;
import com.onstar.cn.mag.enumtype.RemoteCommandsType;
import com.onstar.cn.map.common.LocationType;
import com.onstar.cn.map.common.PoiItemInfo;
import com.onstar.cn.rxconstants.RxConstants;
import com.onstar.cn.vehicle.entity.ErrorInfo;
import com.onstar.cn.vehicle.entity.RequestStatus;
import com.onstar.cn.vehicle.result.PollingResult;
import com.shanghaionstar.R;
import com.shanghaionstar.enumtype.FunctionNameFindId;
import com.shanghaionstar.nav.iview.INavMapView;
import com.shanghaionstar.nav.model.LocateStatus;
import com.shanghaionstar.nav.model.NavInfoModel;
import com.shanghaionstar.nav.service.AbstractMapActivity;
import com.shanghaionstar.nav.service.NavService;
import com.shanghaionstar.sqlite.SearchHistoryImpl;
import com.shanghaionstar.sqlite.TBTHistoryImpl;
import com.shanghaionstar.pin.PinDialogFragment;
import com.shanghaionstar.report.bean.ReportReqParam;
import com.shanghaionstar.utils.AlertDialogUtil;
import com.shanghaionstar.utils.ApplicationUtil;
import com.shanghaionstar.utils.AuthorUtil;
import com.shanghaionstar.utils.BusinessUtil;
import com.shanghaionstar.utils.ErrorCodeUtil;
import com.shanghaionstar.utils.FinalConfigParams;
import com.shanghaionstar.utils.MapHandler;
import com.shanghaionstar.utils.NavHolder;

import rx.Subscription;
import rx.functions.Action1;

/**
 * Created by 6335yz on 2016/7/7.
 */
public class NavMapPresenter extends BasePresenter implements MapHandler.OnMapCallBack {

    private AbstractMapActivity mapActivity;
    private Resources res;
    private INavMapView navMapView;
    private Subscription locateSubscription;
    private Subscription vehicleSubscription;
    private Subscription rxSubscription;

    private NavHolder navHolder;

    private MapHandler mapHandler;
    private NavService navService;
    private FragmentManager fragmentManager;

    @Override
    public void setView(IMVPView view) {
        navMapView = (INavMapView) view;
        super.setView(navMapView);
        rxSubscription = RxBus.getDefault().toObserverable(RxConstants.ALL_PAGE_REFRESH, String.class)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                initOddBtn();
            }
        });

    }

    public NavMapPresenter(IMVPScheduler mvpScheduler, AbstractMapActivity mapActivity, MapHandler mapHandler) {
        super(mvpScheduler);
        this.mapActivity = mapActivity;
        this.mapHandler = mapHandler;
        res = mapActivity.getResources();
        mapHandler.registOnMapCallBack(this);
        registMyLocate();
        registVehicleLocate();
        navService = new NavService(mapActivity);
        fragmentManager = mapActivity.getSupportFragmentManager();
    }

    public void initOddBtn() {
        // 车载导航 ODD
        if (ApplicationUtil.getInstance().isLogin() && BusinessUtil.isServiceFeature(
                FeatureEnum.SENDNAVDESTINATION.value(), mapActivity)) {
            if (navMapView != null) {
                navMapView.showOddBtn(true);
            }
        } else {
            if (navMapView != null) {
                navMapView.showOddBtn(false);
            }
        }
    }

    /**
     * 主动请求位置变化信息
     */
    public void requestMyLocate() {
        navHolder = NavHolder.getInstance(mapActivity);
//        LocateStatus locateStatus = LocateStatus.LOCATED;
        /**
         * 一直报 enum的ordinal（）方法错误
         */
        LocateStatus locateStatus = navHolder.getLocateStatus();
        switch (locateStatus) {
            case LOCATING:
                break;
            case LOCATED:
                if (navHolder.getMyLocation() != null) {
                    mapHandler.geoCoderGps(navHolder.getMyLocation().getLatitude(), navHolder.getMyLocation().getLongitude(), LocationType.MYSELF);
                }
                break;
            case LOCATE_FAIL:
                break;
        }
    }

    public void requestVehicleLocate(Location location) {
        if (location == null) return;
        if (NavHolder.getInstance(mapActivity).getVehicleLocation() != null) {
            mapHandler.geoCoderGps(location.getLatitude(), location.getLongitude(), LocationType.VEHICLE);
        }
    }

    /**
     * 注册广播以接受车辆位置
     */
    private void registVehicleLocate() {
        vehicleSubscription = RxBus.getDefault().toObserverable(RxConstants.VEHICLE_LOCATE, PollingResult.class).subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<PollingResult>() {
                    @Override
                    public void call(PollingResult pollingResult) {
                        if (RequestStatus.Success.getStringValue().equalsIgnoreCase(pollingResult.getRequestStatus())) {
                            BusinessUtil.sendReportByRequestParams(mapActivity, FunctionNameFindId.Mytrip_Locator.getStringValue(), ReportReqParam.getVehicleLocateReqParam(FunctionNameFindId.Map_Locator, true, ""));
                        } else {
                            BusinessUtil.sendReportByRequestParams(mapActivity, FunctionNameFindId.Mytrip_Locator.getStringValue(), ReportReqParam.getVehicleLocateReqParam(FunctionNameFindId.Map_Locator, false, pollingResult.getErrorInfo() == null ? "" : pollingResult.getErrorInfo().getMsg()));
                        }
                        if (NavHolder.getInstance(mapActivity).isShowMap()) {
                            Location location = new Location("");
                            if (!CommonUtil.isNull(pollingResult.getLat())) {
                                location.setLatitude(Double.valueOf(pollingResult.getLat()));
                            }
                            if (!CommonUtil.isNull(pollingResult.getLon())) {
                                location.setLongitude(Double.valueOf(pollingResult.getLon()));
                            }
                            NavHolder.getInstance(mapActivity).setVehicleLocation(location);
                            requestVehicleLocate(location);
                        }
                    }
                });
//        RxSubscriptions.add(vehicleSubscription);
    }

    /**
     * 注册广播以接受位置变更
     */
    private void registMyLocate() {
        locateSubscription = RxBus.getDefault().toObserverable(RxConstants.LOCATE, LocateStatus.class)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<LocateStatus>() {
                    @Override
                    public void call(LocateStatus locateStatus) {
                        requestMyLocate();
                    }
                });
    }

    @Override
    public void onFindLocateSuccess(LocationType locationType) {
        showLocation(locationType);
    }

    @Override
    public void onFindLocateFail() {

    }

    @Override
    public void finish() {
        if(!rxSubscription.isUnsubscribed()){
            rxSubscription.unsubscribe();
        }
        locateSubscription.unsubscribe();
        vehicleSubscription.unsubscribe();
//        RxSubscriptions.remove(vehicleSubscription);
        mapHandler.removeOnMapCallBack();
    }

    //地图上显示的poi点的poiItemInfo
    private PoiItemInfo mapPoi_PoiItemInfo;

    public void showLocation(LocationType locationType) {
        Location location;
        switch (locationType) {
            case MYSELF:
                try {
                    mapHandler.setMapPoi_PoiItemInfo(mapHandler.getMyLocationPoiItemInfo());
                    mapActivity.getNavDataHolder().setCurrentMapPoi(mapHandler.getMyLocationPoiItemInfo());
                    location = navHolder.getMyLocation();
                    if (location != null) {
                        mapHandler.setLocationPointer(locationType, location.getLatitude(), location.getLongitude());
                        mapHandler.showLocation(locationType, mapHandler.getMyLocationPoiItemInfo());
                    }
                } catch (Exception e) {
//                    getLogger().e(
//                            "===showLocation(LocationType locationType) locationType=" + locationType.toString() + " "
//                                    + e.getMessage(), e);
                }
                break;
            case VEHICLE:
                try {
                    mapHandler.setMapPoi_PoiItemInfo(mapHandler.getVehicleLocationPoiItemInfo());
//                    //当poi点显示在地图上的时候弹出bottom view
//                    if (mapPoi_PoiItemInfo != null) {
//                        myLocationSnippet = mapPoi_PoiItemInfo.getSnippet();
//                        myLocationtitle = mapPoi_PoiItemInfo.getTitle();
//                    }
//                    //不显示清理按钮
//                    nav_clean_map_view.setVisibility(View.VISIBLE);
                    location = navHolder.getVehicleLocation();
                    if (location != null) {
                        mapHandler.setLocationPointer(locationType, location.getLatitude(), location.getLongitude());
                        mapHandler.showLocation(locationType, mapHandler.getVehicleLocationPoiItemInfo());
                    }
                    if (navMapView != null && mapActivity.getNavDataHolder().getVehiclePoi() != null) {
                        navMapView.showBottomView(mapActivity.getNavDataHolder().getVehiclePoi(), true);
                    }
                } catch (Exception e) {
                    LogManager.getInstance().e(e.getMessage());
                }
                break;
            case POI:
                break;
            default:
                break;
        }
    }

    public void sendTbtOrOdd(final PoiItemInfo poiItemInfo, final RemoteCommandsType remoteCommandsType) {
        if(ApplicationUtil.getInstance().isCommanding){
            ApplicationUtil.getInstance().controlCommand(mapActivity);
            return;
        }else {
            ApplicationUtil.getInstance().isCommanding = true;
        }
        if (validateTbtOrOdd(poiItemInfo, remoteCommandsType)) {
//            BusinessUtil.sendReportByClickType(mapActivity, FunctionNameFindId.POIviewTBT.getStringValue());
            NavInfoModel navInfoModel = new NavInfoModel();
            navInfoModel.remoteCommandsType = remoteCommandsType;
            navInfoModel.poiItemInfo = poiItemInfo;
            new AuthorUtil().reauthForNoPin(mapActivity, new Action1() {
                @Override
                public void call(Object o) {
                    NavInfoModel tmp = new NavInfoModel();
                    tmp.remoteCommandsType = remoteCommandsType;
                    tmp.poiItemInfo = poiItemInfo;
                    doNavCommand(tmp);
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    ApplicationUtil.getInstance().isCommanding = false;
                    BusinessUtil.sendReportByRequestParams(mapActivity, FunctionNameFindId.SendingTBT.getStringValue(), ReportReqParam.getTBTOddReportParams(remoteCommandsType, false, throwable.getMessage()));
                    if (navMapView != null) {
                        ErrorInfo errorInfo = ErrorCodeUtil.getErrorInfoByHttpException(mapActivity, new HttpException("", throwable.getMessage()));
                        navMapView.onResponseError(new OnStarException("", errorInfo.getMsg()));
                    }
                }
            });
        }
    }

    private boolean validateTbtOrOdd(PoiItemInfo poiItemInfo, RemoteCommandsType remoteCommandsType) {
        if (poiItemInfo == null) return false;
        if (remoteCommandsType != RemoteCommandsType.COMMANDS_TBT_ROUTE && remoteCommandsType != RemoteCommandsType.COMMANDS_NAV_DESTINATION)
            return false;
        if (!ApplicationUtil.getInstance().isLogin())
            return false;
        if (ApplicationUtil.getInstance().isAutoLogings()) {
            if (navMapView != null) {
                navMapView.onResponseError(new OnStarException("", mapActivity.getString(R.string.loading)));
            }
        }
        if (!BusinessUtil.checkDriverOrProxyAndShowDialog(mapActivity)) {
            return false;
        }
        if (!BusinessUtil.checkPackageRight(Constants.ENTITLEMENT_M05NAVIGATION, mapActivity, true)) {
            return false;
        }
        //判断是否正在执行车辆的相关操作
        if (BusinessUtil.checkInProgressCommand(mapActivity, null, false)) {
            AlertDialogUtil.showAlertDialog(mapActivity, mapActivity.getString(R.string.dialog_warning),
                    mapActivity.getString(R.string.service_inProcess_alert));
//            BusinessUtil.updateConfigValue(FinalConfigParams.SHARE_DESTINATION, "-1", mapActivity);
            return false;
        }
        return true;
    }

    private void doNavCommand(final NavInfoModel navInfoModel) {
        BusinessUtil.sendReportByClickType(mapActivity, FunctionNameFindId.Mytrip_Navigation.getStringValue());
        subscription = navService.doNavCommand(navInfoModel)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String requestId) {
                        if (navMapView != null) {
                            navMapView.showCommandLoading(true);
                        }
                        if (navInfoModel.remoteCommandsType == RemoteCommandsType.COMMANDS_NAV_DESTINATION || navInfoModel.remoteCommandsType == RemoteCommandsType.COMMANDS_TBT_ROUTE) {
                            TBTHistoryImpl tbtHistoryImpl = new TBTHistoryImpl(mapActivity);
                            SearchHistoryImpl searchHistoryImpl = new SearchHistoryImpl(mapActivity);
                            tbtHistoryImpl.saveHistoryToSql(requestId, navInfoModel.poiItemInfo, null, true);
                            //将下发历史保存到历史记录中
                            searchHistoryImpl.saveSearchHistory(navInfoModel.poiItemInfo);
                            RxBus.getDefault().post(RxConstants.ALL_PAGE_REFRESH, RxConstants.NAV_SAVE_POI);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //里面抛出的Error信息
                        if (navMapView != null) {
                            navMapView.onResponseError((OnStarException) throwable);
                        }
                    }
                });
    }


    public void showPinOrNot() {
        if (BusinessUtil.isAutoSendPin(RemoteCommandsType.COMMANDS_LOCATION, mapActivity)) {
            if (navMapView != null) {
                navMapView.showMapLoading(true, mapActivity.getString(R.string.locationing_vehicle));
            }
            getVehicleLocation();
        } else {
            showPinDialogFragment();
        }
    }

    private void showPinDialogFragment() {
        PinDialogFragment pinDialogFragment = PinDialogFragment.newInstance(RemoteCommandsType.COMMANDS_LOCATION, RxConstants.NAV_MAP_PAGE);
        pinDialogFragment.show(fragmentManager, "pin_dialog");
    }

    public void getVehicleLocation() {
        NavInfoModel navInfoModel = new NavInfoModel();
        navInfoModel.remoteCommandsType = RemoteCommandsType.COMMANDS_LOCATION;
        subscription = navService.doNavCommand(navInfoModel)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        if (navMapView != null) {
                            navMapView.showMapLoading(false, "");
                            navMapView.showCommandLoading(true);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //里面抛出的Error信息
                        if (navMapView != null) {
                            BusinessUtil.sendReportByRequestParams(mapActivity, FunctionNameFindId.Mytrip_Navigation.getStringValue(), ReportReqParam.getVehicleLocateReqParam(FunctionNameFindId.Map_Locator,false, throwable.getMessage()));
                            navMapView.showMapLoading(false, "");
                            navMapView.onResponseError((OnStarException) throwable);
                        }
                    }
                });
    }

    public void findVehicleLocation() {
//        BusinessUtil.sendReportByClickType(mapActivity, FunctionNameFindId.GetVehicleLocationButton.getStringValue());
        if (validateVehicleCommand()) {
            showPinOrNot();
        }
    }

    private boolean validateVehicleCommand() {
        if (!CommonUtil.checkNetWorkState(mapActivity)) return false;
        if (!BusinessUtil.checkOwnerAndShowDialog(mapActivity, navMapView)) return false;
        if (!BusinessUtil.checkPackageRight(Constants.ENTITLEMENT_M06FIND_CAR, mapActivity, true))
            return false;
        if (!ApplicationUtil.getInstance().isBBWC()) {
            if (navMapView != null) {
                navMapView.onResponseError(new OnStarException("", mapActivity.getString(R.string.vehicle_bbwc_error)));
            }
            return false;
        }
        if (!ApplicationUtil.getInstance().isFmvOpt()) {
            if (navMapView != null) {
                navMapView.onResponseError(new OnStarException("", mapActivity.getString(R.string.opt_out_alert)));
            }
            return false;
        }
        if (BusinessUtil.checkInProgressCommand(mapActivity, null)) return false;// 传空代表遥控页的操作
        return !BusinessUtil.checkInProgressCommand(mapActivity, RemoteCommandsType.COMMANDS_LOCATION);
    }


}
